/**
 * file :	db_interface.h
 * author :	bushaofeng
 * created :	2013-01-29 00:03
 * func : api接口，直接连接db
 */

#ifndef	__DB_INTERFACE_H_
#define	__DB_INTERFACE_H_

#include <iostream>
#include "bs_type.h"
#include "bs_error.h"
#include "mongoclient.h"
#include "mongo/client/dbclient.h"
#include "mongo/bson/bson.h"
#include "mongo/db/json.h"

#define DB_PROJECTS     "global.project"
#define DB_COUNTER      "counter"

class DBInterface{
    public:
        /**
         * 对于新建项目要调用该构造函数
         */
        DBInterface(MongoClient& db):m_db(db){}
        /**
         * 对于非新建项目调用该构造函数
         */
        DBInterface(MongoClient& db, string token);

        /**
         * 新建一个project
         */
        string createProject(string project);

        /**
         * 添加一个user
         */
        long long addUser(BSONObj user);

        /**
         * 登录
         */
        BSONObj login(string user, string pwd);
        /**
         * 更新user
         */
        state_t updUser(string user, BSONObj obj);
        /**
         * 获取user
         */
        BSONObj getUser(string user);
        /**
         * 添加user的关注
         */
        state_t addFollow(string user, string follow);
        /**
         * 获取user的关注列表
         */
        BSONObj getFollows(string user, int start=0, int num=0);
        /**
         * 删除user的关注
         */
        state_t delFollow(string user, string follow);
        /**
         * 添加user的粉丝（一个人的好友关系为2个表，我的关注表，我的粉丝表即关注我的人）
         */
        state_t addFan(string user, string fan);
        /**
         * 获取关注user的列表
         */
        BSONObj getFans(string user, int start = 0, int num = 0);
        /**
         * 添加一个发表
         */
        long long addTopic(BSONObj topic);
        /**
         * 获取user的发表
         */
        BSONObj getTopics(string user, int start=0, int num=0);
        /**
         * 获取一个发表
         */
        BSONObj getTopic(long long topic);
        /**
         * 获取评论
         */
        BSONObj getPosts(int64_t topic);
        /**
         * 获取user的位置列表
         */
        BSONObj getLocations(string user, int start = 0, int num = 0);
        /**
         * 获取附近user
         */
        BSONObj getNearUsers(double x, double y, int start=0, int num=0);
        /**
         * 获取附近发表
         */
        BSONObj getNearTopics(double x, double y, int start=0, int num=0);

    private:
        bool setCounter(string coll){
            BSONObj obj = m_db.query(m_project+DB_COUNTER, BSON("_id"<<coll));
            if(obj.nFields()<1){
                m_db.insert(m_project+DB_COUNTER, BSON("_id"<<coll<<"counter"<<(long long)1));
            }
            return true;
        }
        int64_t getCounterId(string table);

        bool setIndexs(){
            m_db.ensureIndex(m_users, BSON("user"<<1), true, m_users+"_user");
            m_db.ensureIndex(m_users, BSON("gps"<<"2d"), false, m_users+"_gps");
            m_db.ensureIndex(m_follows, BSON("user"<<1), true, m_follows+"_user");
            m_db.ensureIndex(m_fans, BSON("user"<<1), true, m_fans+"_user");
            m_db.ensureIndex(m_locations, BSON("user"<<1), true, m_locations+"_user");
            m_db.ensureIndex(m_topics, BSON("user"<<1), false, m_topics+"_user");
            m_db.ensureIndex(m_topics, BSON("_tm"<<-1<<"user"<<1), false, m_topics+"_time");
            m_db.ensureIndex(m_topics, BSON("gps"<<"2d"), false, m_topics+"_gps");
            return true;
        }
    private:

        MongoClient&    m_db;
        string          m_project;

        string  m_follows;
        string  m_users;
        string  m_fans;
        string  m_topics;
        string  m_posts;
        string  m_locations;
        string  m_inbox;
        string  m_counter;
};

#endif
